package com.sinszm.sofa.job;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.sinszm.sofa.SzmQuartzProperties;
import com.sinszm.sofa.annotation.QJob;
import com.sinszm.sofa.service.IQuartzService;
import com.sinszm.sofa.util.BaseUtil;
import com.sinszm.sofa.vo.JobParam;
import lombok.SneakyThrows;
import org.quartz.Job;
import org.quartz.JobExecutionContext;


/**
 * 业务任务初始化监听job
 *
 * @author admin
 */
public class CommandLineRunnerJob implements Job {

    @SneakyThrows
    @Override
    public void execute(JobExecutionContext context) {
        //读取实例
        IQuartzService iQuartzService = SpringUtil.getBean(IQuartzService.class);
        SzmQuartzProperties szmQuartzProperties = SpringUtil.getBean(SzmQuartzProperties.class);
        //逻辑处理
        for (Class<?> jobClass : szmQuartzProperties.jobClasses().getBasePackagesClasses()) {
            ThreadUtil.execAsync(() -> executeJob(jobClass, iQuartzService));
        }
    }

    private void executeJob(Class<?> jobClass, IQuartzService iQuartzService) {
        QJob job = AnnotationUtil.getAnnotation(jobClass, QJob.class);
        if (job == null) {
            return;
        }
        if (BaseUtil.isEmpty(job.cron())) {
            return;
        }
        if (BaseUtil.isEmpty(job.methodName())) {
            return;
        }
        boolean state = checkJobMethod(jobClass, job.methodName());
        if (!state) {
            return;
        }
        String group = BaseUtil.trim(BaseUtil.isEmpty(job.group()) ? jobClass.getName() : job.group());
        String name = BaseUtil.trim(BaseUtil.isEmpty(job.name()) ? jobClass.getSimpleName() + "." + BaseUtil.trim(job.methodName()) : job.name());
        String cron = BaseUtil.trim(job.cron());
        //检查任务是否存在，如果存在则不初始化创建任务
        if (iQuartzService.checkExists(name, group)) {
            return;
        }
        //初始化创建一个任务
        iQuartzService.addJob(
                name,
                group,
                cron,
                JobParam.builder()
                        .clazz(jobClass)
                        .methodName(job.methodName())
                        .build()
        );
    }

    private boolean checkJobMethod(Class<?> jobClass, String methodName) {
        try {
            return ReflectUtil.getMethod(jobClass, methodName) != null;
        } catch (SecurityException e) {
            return false;
        }
    }
}
